'use strict';

// 课表管理

const scheduleModel = require('../models/schedule.model');
const classAttendanceModel = require('../models/class_attendance.model');
const classroomModel = require('../models/classroom.model');
const classgradeModel = require('../models/classgrade.model');
const ipcModel = require('../models/ipc.model');
const userModel = require('../models/user.model');
const Code = require('../common/error_code');
const httpUtil = require('../utils/http');
const fs = require('fs');
const XLSX = require('xlsx');
const util = require('util');
const Util = require('../utils/hobot_util');
const moment = require('moment');

/**
 * 课表管理
 */


//  导入课表
async function import_schedule(ctx) {
    try{
        const file = ctx.req.file.buffer;
        const workBook = XLSX.read(file);
        const workSheet = workBook.Sheets['Sheet1'];
        const tableData = XLSX.utils.sheet_to_json(workSheet)
        const weekObj = {
            '周天':0,
            '周日':0,
            '周一':1,
            '周二':2,
            '周三':3,
            '周四':4,
            '周五':5,
            '周六':6
        }
        const on_class_day =[] //上课星期集合
        // 提取的字段
        const tableKeyMap = {
            '在读学校': 'school_name',
            '年级': 'grade_name',
            '班级编码': 'class_num',
            '班级名称': 'class_name',
            '项目':'class_type',
            '主讲教师':'class_teacher',
            // '课表编号': 'schedule_num',
            // '课表名称': 'schedule_name',
            // '课次编号': 'class_time_num',
            // '课次名称': 'class_time_name',
            '上课日期': 'class_date_range',
            '上课时段': 'class_time_range',
            '上课时间': 'class_start_time',
            '下课时间': 'class_end_time',
            '学员编码': 'student_num',
            '姓名':'student_name',
            '学员电话':'student_phone'
        };
        const tableDataStandard = [];
        const class_collections = {}; //缓存班级，同一个班级只会存一条，新增学生即可
        for (let i = 0; i < tableData.length; i++) {
            const item = tableData[i];
            const dataTemp = {};
            let childItem = {};
            let isExist = false; //是否新增班级
            if(item['班级编码']&&class_collections[item['班级编码']]){
                childItem = class_collections[item['班级编码']]
                isExist = true
            }else if(item['班级编码']){
                childItem = {
                    student_collection:[]
                }
                class_collections[item['班级编码']] = childItem
            }else{
                return ctx.error({
                    code: Code.RET_USER_REGISTER_BATCH_ERR_PARAM.code,
                    msg: util.format(Code.RET_USER_REGISTER_BATCH_ERR_PARAM.msg,
                        util.format('第%s行 %s 是空值', i + 1, '班级编码'))
                });
            }
            const dateRange_regex = /(\d{4}\/\d{2}\/\d{2})~(\d{4}\/\d{2}\/\d{2})/
            const timeRange_regex = /(\d{2}:\d{2})-(\d{2}:\d{2})/
            for (let column in item) {
                const formatColumn = column.toString().trim();
                tableKeyMap[formatColumn] && (dataTemp[tableKeyMap[formatColumn]] = item[column])
                const v = item[column].trim();
                if (column == '上课日期 ' && !dateRange_regex.test(v)) {
                    return ctx.error({
                        code: Code.RET_USER_REGISTER_BATCH_ERR_PARAM.code,
                        msg: util.format(Code.RET_USER_REGISTER_BATCH_ERR_PARAM.msg,
                            util.format('第%s行 的日期格式', i + 1))
                    });
                }
                if (column == '上课时段 ' && !timeRange_regex.test(v)) {
                    return ctx.error({
                        code: Code.RET_USER_REGISTER_BATCH_ERR_PARAM.code,
                        msg: util.format(Code.RET_USER_REGISTER_BATCH_ERR_PARAM.msg,
                            util.format('第%s行 的上课时段格式', i + 1))
                    });
                }
            }
            //校验是否缺少必选项
            for (var key of Object.keys(dataTemp)) {
                if (!dataTemp[key].trim()) {
                    delete dataTemp[key]
                }
            }
            let column_name = '';
            if(isExist){
                if (!dataTemp.student_name) {
                    column_name = '上课学生';
                } else if (!dataTemp.student_num) {
                    column_name = '学员编码';
                }
            }else{
                if (!dataTemp.class_num) {
                    column_name = '班级编码';
                } else if (!dataTemp.class_type) {
                    column_name = '项目';
                } else if (!dataTemp.class_date_range) {
                    column_name = '上课日期';
                } else if (!dataTemp.class_time_range) {
                    column_name = '上课时段';
                } else if (!dataTemp.student_name) {
                    column_name = '上课学生';
                } else if (!dataTemp.student_num) {
                    column_name = '学员编码';
                } else {
                    const weekRange = dataTemp['class_time_range'].split(';')
                    weekRange.forEach(item=>{
                        item=item.trim().slice(0,2)
                        if(weekObj[item]!=undefined&&!on_class_day.includes(weekObj[item])){
                            on_class_day.push(weekObj[item])
                        }
                    })
                    const date_range_array = dateRange_regex.exec(dataTemp['class_date_range'])
                    const time_range_array = timeRange_regex.exec(dataTemp['class_time_range'])
                    dataTemp.class_start_date = +new Date(date_range_array[1])
                    dataTemp.class_end_date = +new Date(date_range_array[2]+' 23:59:59')
                    dataTemp.class_start_time = time_range_array[1].replace(':','')
                    dataTemp.class_end_time = time_range_array[2].replace(':','')
                    if(dataTemp.class_start_date>=dataTemp.class_end_date){
                        return ctx.error(Code.REQUEST_ERROR(`上课开始时间段不能大于结束时间段`))
                    }
                    if(dataTemp.class_start_time>=dataTemp.class_end_time){
                        return ctx.error(Code.REQUEST_ERROR(`上课开始时间不能大于结束时间`))
                    }
                }
            }
            if (column_name) {
                return ctx.error({
                    code: Code.RET_USER_REGISTER_BATCH_ERR_PARAM.code,
                    msg: util.format(Code.RET_USER_REGISTER_BATCH_ERR_PARAM.msg,
                        util.format('第%s行 %s 是空值', i + 1, column_name))
                });
            }else{
                childItem.student_collection.push({
                    student_num:(dataTemp.student_num).trim(),
                    student_name:dataTemp.student_name
                })
            }

            !isExist && (tableDataStandard.push({
                ...dataTemp,
                ...childItem,
                on_class_day
            }))
        }

        // 转换完成的数据，已经通过校验，直接插入数据库
        for(let item of tableDataStandard){
            const data = await scheduleModel.findOne({class_num:item.class_num})
            if(data){
                return ctx.error(Code.REQUEST_ERROR(`班级编码:${item.class_num}已存在`))
            }      
            // 生成课表
            await scheduleModel.create(item);

            // 生成班级
            const gradeParams = {
                name:item.class_name,
                num:item.class_num,
                related_students:item.student_collection
            }
            await classgradeModel.create(gradeParams)
        }
        // tableDataStandard.forEach(async function (item) {
        //     const data = await scheduleModel.findOne({class_num:item.class_num})
        //     if(data){
        //         return ctx.error(Code.REQUEST_ERROR(`班级编号:${item.class_num}已存在`))
        //     }
        //     await scheduleModel.create(item);
        // });
        if(tableDataStandard.length===0){
            return ctx.error(Code.REQUEST_ERROR('无有效数据'));
        }
        ctx.success(Code.REQUEST_SUCCESS('导入成功'));
    }catch(err){
        console.log(err)
        ctx.error()
    }
}

//  删除课表
async function delete_schedule(ctx){
    const params = ctx.request.body
    try{
        if(!params || typeof params !=='object' || !params._id) return ctx.error(Code.REQUEST_ERROR('请选择要删除的课表'))
        if(Array.isArray(params._id)){
            for(let id of params._id){
                const data = await scheduleModel.findOneAndRemove({_id:id}) 
                if(data){
                    await classAttendanceModel.remove({class_num:data.class_num})
                    await classgradeModel.remove({num:data.class_num})
                }
            }
        }else{
            const data = await scheduleModel.findOneAndRemove({_id:params._id})
            if(data){
                await classAttendanceModel.remove({
                    class_num:data.class_num,
                })
                await classgradeModel.remove({num:data.class_num})
            }
        }
        return ctx.success(Code.REQUEST_SUCCESS('删除成功'))
    }catch(err){
        return ctx.error(Code.REQUEST_ERROR('删除失败'))
    }
}
// 绑定教室
async function bind_classroom(ctx){
    const isDev = ctx.request.host.indexOf('localhost')>-1
    const params = ctx.request.body;
    // 校验参数
    if (!params.schedule_id || !params.classroom_id) {
        return ctx.error(Code.RET_USER_QUERY_ERR_PARAM);
    }
    const classroom = await classroomModel.findById(params.classroom_id)
    if(!classroom){
        return ctx.error(Code.REQUEST_ERROR('教室不存在'));
    }
    const schedule = await scheduleModel.findOneAndUpdate({_id:params.schedule_id},{
        group_name:classroom.group_name,
        campus_name:classroom.campus_name,
        classroom_id:classroom._id,
        classroom_num:classroom.num,
        classroom_name:classroom.name
    })
    if(!schedule){
        return ctx.error(Code.REQUEST_ERROR('课表不存在'));
    }
    try{
        const class_start_date = schedule.class_start_date
        const class_end_date = schedule.class_end_date
        const on_class_day = schedule.on_class_day || []
        const one_day_time = 24*60*60*1000
        const tempArray = new Array(Math.ceil((class_end_date - class_start_date)/one_day_time))
        const student_collection = schedule.student_collection;
        const related_devices = classroom.related_devices;
        // 保存学生信息到设备
        // let isDeviceError = false
        // let deviceErrorHas = {} //异常设备集合
        // let deviceErrorMsg = ''
        for(let student of student_collection){
            const user = await userModel.findOne({s_num:student.student_num})
            if(user){
                student.student_id = user._id
                for(let _device of related_devices){
                    const device = await ipcModel.findOneAndUpdate({_id:_device.device_id},{class_name:schedule.class_name})
                    
                    // 这里不重新存底库，已原底库为准
                    // if(device&&!deviceErrorHas[device._id]){
                    //     let studentParams = {
                    //         Name:'personListRequest',
                    //         UUID:device.device_uuid,
                    //         ChannelNo: device.channel_num,
                    //         Session: device.register_session,
                    //         TimeStamp:Math.floor(+new Date()/1000),
                    //         Sign:'',
                    //         Data:{
                    //             Action:'addPerson',
                    //             PersonType:2,
                    //             PersonInfo:{
                    //                 PersonId: user._id,
                    //                 PersonName: user.u_nm,
                    //                 Sex: user.u_sx,
                    //                 IDCard: user.user_idcard,
                    //                 Nation: user.user_nation,
                    //                 Birthday: user.user_birthday,
                    //                 Phone: user.u_pn,
                    //                 Address: user.user_address,
                    //                 LimitTime: user.user_limit, 
                    //                 PersonExtension:{
                    //                     PersonCode1: user.s_num, //学号
                    //                     PersonCode2: user.s_school, //学校
                    //                     PersonCode3: user.s_class, //班级
                    //                     PersonData1: user.u_em //邮箱
                    //                 },
                    //                 PersonPhoto: user.u_hp
                    //             },
                    //         },
                    //     }
                    //     // 学生信息存入设备
                    //     try{
                    //         const res = await httpUtil.postWithTimeout(`http://${isDev?device.device_ip:'127.0.0.1'}:8011/Request`,studentParams,20*1000)
                    //         if(res.Code===2){
                    //             // 超时
                    //             isDeviceError = true
                    //             deviceErrorHas[device._id] = true
                    //             deviceErrorMsg+=`${device.d_nm}(${device.device_num})、`
                    //         }else if(res.Code === 1110){
                    //             // 底库已存在执行编辑
                    //             studentParams.Data.Action = 'editPerson'
                    //             await httpUtil.postWithTimeout(`http://${isDev?device.device_ip:'127.0.0.1'}:8011/Request`,studentParams,20*1000)
                    //         }
                    //     }catch(err){
                    //         console.log(err)
                    //         return ctx.error(Code.REQUEST_ERROR('设备异常,请检查设备是否正常连接'))
                    //     }
                    // }
                }
            }
        }
        // if(isDeviceError){
        //     return ctx.error(Code.REQUEST_ERROR(`以下设备：${deviceErrorMsg.slice(0,-1)}；异常，请检查设备是否正常连接`))
        // }
        for(let i=0;i<tempArray.length;i++){
            // 判断是否属于上课日期
            const currentDay = new Date(class_start_date+one_day_time*i).getDay();
            if(on_class_day&&on_class_day.length&&!on_class_day.includes(currentDay)){
                continue
            }
            const newAttendance = {
                // 课表信息汇总
                class_teacher:schedule.class_teacher,
                class_type:schedule.class_type, //课程名称
                class_num:schedule.class_num,//班级编号
                class_name:schedule.class_name,//班级名称
                schedule_num:schedule.schedule_num,//课表编号
                schedule_name:schedule.schedule_name,//课表名称

                attendance_start_date:class_start_date+one_day_time*i,
                attendance_end_date:class_start_date+one_day_time*(i+1),
                class_start_time:schedule.class_start_time,
                class_end_time:schedule.class_end_time,
                student_collection:schedule.student_collection,
                // 教室信息汇总
                group_name:classroom.group_name, //集团名称
                campus_name:classroom.campus_name, //上课校区
                classroom_id:classroom._id,
                classroom_name:classroom.name,
                classroom_num:classroom.num,
                device_collection:classroom.related_devices,
            } 
            // 查看更新
            const oldAttendance = await classAttendanceModel.findOneAndUpdate({
                attendance_start_date:class_start_date+one_day_time*i,
                class_num:schedule.class_num,
            },{
                group_name:classroom.group_name, //集团名称
                campus_name:classroom.campus_name, //上课校区
                classroom_id:classroom._id,
                classroom_name:classroom.name,
                classroom_num:classroom.num,
                device_collection:classroom.related_devices,
            })
            if(!oldAttendance){
                // 不存在就新增
                await classAttendanceModel.create(newAttendance)
            }
        }
        return ctx.success(Code.REQUEST_SUCCESS('绑定教室成功'))
    }catch(err){
        console.log(err)
        return ctx.error(Code.REQUEST_ERROR('服务端错误'))
    }
}


// 课表
async function query(ctx) {
    const params = ctx.request.body;
    // 校验参数
    if (!params.page_num || !params.page_size) {
        return ctx.error(Code.RET_USER_QUERY_ERR_PARAM);
    }
    let cdt = {
    };
    if (params.class_name) {
        cdt.class_name = { $regex: params.class_name };
    }
    if (params.class_type) {
        cdt.class_type = { $regex: params.class_type };
    }
    if (params.group_name) {
        cdt.group_name = { $regex: params.group_name };
    }
    if (params.campus_name) {
        cdt.campus_name = { $regex: params.campus_name };
    }
    if (params.class_time_name) {
        cdt.class_time_name = { $regex: params.class_time_name };
    }
    if (params.schedule_name) {
        cdt.schedule_name = { $regex: params.schedule_name };
    }
    if(params.class_start_time&&params.class_end_time){
        cdt.class_start_time = {
            $gte: params.class_start_time
        }
        cdt.class_start_time = {
            $lte: params.class_end_time
        }
    }
    const users = await Util.pageQuery(params.page_num, params.page_size, scheduleModel,
        cdt, '', '', {_id: -1});
    users.results.forEach(item=>{
        if(item.class_start_time&&item.class_end_time){
            const array1 = item.class_start_time.split('')
            item.class_start_time = array1.slice(0,2).concat(':',array1.slice(2)).join('')
            const array2 = item.class_end_time.split('')
            item.class_end_time = array2.slice(0,2).concat(':',array2.slice(2)).join('')
        }
    })
    ctx.success(Code.REQUEST_SUCCESS('查询成功'), {
        page_num: params.page_num,
        page_size: params.page_size,
        total: users.total,
        result: users.results
    });
}

// 导入课表
exports.import_schedule = import_schedule;

// 删除课表
exports.delete_schedule = delete_schedule;

// 绑定教室
exports.bind_classroom = bind_classroom;

exports.query = query;